﻿namespace EFS.RC.SupervisorCentral.Agents
{
	public class StatusList
	{
		#region Locals
		/// agents list
		private System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status> list =
			new System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status>();
		#endregion

		/// Implicit constructor
		public StatusList()
		{
		}

		/// Explicit constructor
		public StatusList(EFS.RC.CC.Messages.Agents.StatusList messageAll)
		{
			LoadFrom(messageAll);
		}

		/// Explicit constructor
		public StatusList(EFS.RC.CC.Messages.Agents.Status[] statusArray)
		{
			LoadFrom(statusArray);
		}

		#region SyncMethods
		/// Property Items: Get
		public EFS.RC.CC.Messages.Agents.Status[] Items
		{
			get
			{
				// lock list
				lock (this.list)
				{
					return this.list.ToArray();
				}
			}
		}

		/// Property AgentInfo: Get
		public EFS.RC.CC.Messages.Agents.Status this[System.String sip]
		{
			get
			{
				lock (this.list)
				{
					return GetBySIP(sip);
				}
			}
			set
			{
				// verify
				EFS.Common.Verify.Reference(value, "value");

				lock (this.list)
				{
					// Add
					if (null == GetBySIP(sip))
					{
						Add_Internal(value);
					}
					// Update
					else
					{
						Update_Internal(value);
					}
				}
			}
		}

		/// Load from received message
		public void LoadFrom(EFS.RC.CC.Messages.Agents.StatusList messageAll)
		{
			lock (this.list)
			{
				// clear
				this.list.Clear();

				// add
				foreach (EFS.RC.CC.Messages.Agents.Status agentInfo in messageAll.Items)
				{
					Add_Internal(agentInfo);
				}
			}
		}

		/// Load from received message
		public void LoadFrom(EFS.RC.CC.Messages.Agents.Status[] statusArray)
		{
			lock (this.list)
			{
				// clear
				this.list.Clear();

				// add
				foreach (EFS.RC.CC.Messages.Agents.Status agentInfo in statusArray)
				{
					Add_Internal(agentInfo);
				}
			}
		}

		/// Exists by sip
		public System.Boolean Exists(System.String sip)
		{
			lock (this.list)
			{
				return null != GetBySIP(sip);
			}
		}

		/// Add to List
		public System.Boolean Add(EFS.RC.CC.Messages.Agents.Status agentInfo)
		{
			lock (this.list)
			{
				return Add_Internal(agentInfo);
			}
		}

		/// Update in List
		public System.Boolean Update(EFS.RC.CC.Messages.Agents.Status agentInfo)
		{
			lock (this.list)
			{
				return Update_Internal(agentInfo);
			}
		}

		/// Remove from List
		public void Remove(System.String sip)
		{
			lock (this.list)
			{
				System.Int32? index = null;

				// cicle all
				for (System.Int32 i = 0; i < this.list.Count; ++i)
				{
					EFS.RC.CC.Messages.Agents.Status agentInfo = this.list[i];
					if (0 == System.String.Compare(agentInfo.SIP, sip, true))
					{
						index = i;
						break;
					}
				}

				// test index
				if (index.HasValue)
				{
					this.list.RemoveAt(index.Value);
				}
			}
		}

		/// Remove from List
		public void Remove(System.Int32 index)
		{
			lock (this.list)
			{
				this.list.RemoveAt(index);
			}
		}

		/// Clear
		public void Clear()
		{
			lock (this.list)
			{
				this.list.Clear();
			}
		}

		/// Filter using the given arguments
		public EFS.RC.CC.Messages.Agents.Status[] Filter(
			System.String sip,
			System.Boolean? isOnline,
			System.Boolean? inSession,
			System.Boolean? inWrap,
			System.Boolean? isAvailable,
			System.Int32? skillID,
			System.Boolean acdInclude,
			System.String acd)
		{
			// create list
			System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status> retValue =
				new System.Collections.Generic.List<EFS.RC.CC.Messages.Agents.Status>();

			// get items
			EFS.RC.CC.Messages.Agents.Status[] itemsLocal = Items;

			// cicle all
			foreach (EFS.RC.CC.Messages.Agents.Status agentStatus in itemsLocal)
			{
				if (agentStatus.CheckACD(sip, isOnline, inSession, inWrap, isAvailable, skillID, acdInclude, acd))
				{
					retValue.Add(agentStatus);
				}
			}

			// ok
			return retValue.ToArray();
		}
		#endregion

		#region UnSyncMethods
		/// Gets an agent by SIP
		private EFS.RC.CC.Messages.Agents.Status GetBySIP(System.String sip)
		{
			// get array copy
			EFS.RC.CC.Messages.Agents.Status[] items = this.list.ToArray();

			// cicle all
			foreach (EFS.RC.CC.Messages.Agents.Status agentInfo in items)
			{
				if (0 == System.String.Compare(agentInfo.SIP, sip, true))
				{
					return agentInfo;
				}
			}

			// none
			return null;
		}

		/// Add to List
		private System.Boolean Add_Internal(EFS.RC.CC.Messages.Agents.Status agentInfo)
		{
			// check
			EFS.Common.Verify.Reference(agentInfo, "agentInfo");

			// test of exists
			if (null != GetBySIP(agentInfo.SIP))
			{
				return false;
			}

			// add
			this.list.Add(agentInfo);

			// ok
			return true;
		}

		/// Update in List
		private System.Boolean Update_Internal(EFS.RC.CC.Messages.Agents.Status agentInfo)
		{
			// check
			EFS.Common.Verify.Reference(agentInfo, "agentInfo");

			// cicle all
			for (System.Int32 i = 0; i < this.list.Count; ++i)
			{
				EFS.RC.CC.Messages.Agents.Status agentInfoTemp = this.list[i];
				if (0 == System.String.Compare(agentInfo.SIP, agentInfoTemp.SIP, true))
				{
					this.list[i] = agentInfo;
					return true;
				}
			}

			// not updated
			return false;
		}
		#endregion
	}

}